package com.kuzlak.cms.module.sys.controller;


import cn.hutool.json.JSONUtil;
import com.kuzlak.cms.bean.Result;
import com.kuzlak.cms.component.TokenAdminUtils;
import com.kuzlak.cms.config.ConstantHeader;
import com.kuzlak.cms.libraries.IpUtil;
import com.kuzlak.cms.libraries.IpUtils;
import com.kuzlak.cms.module.sys.bean.AccountsVO;
import com.kuzlak.cms.module.sys.entity.SysAccounts;
import com.kuzlak.cms.module.sys.entity.SysLoginLog;
import com.kuzlak.cms.module.sys.service.SysUserRoleService;
import com.kuzlak.cms.security.LoginUserDetails;
import com.kuzlak.cms.utils.JwtUtils;
import com.kuzlak.cms.utils.RedisClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;

@RequestMapping("/auth")
@RestController
public class LoginController {

    @Resource
    private AuthenticationManager authenticationManager;
    @Resource
    private RedisClient redisClient;
    @Autowired
    private SysUserRoleService userRoleService;
    @Autowired
    private TokenAdminUtils tokenAdminUtils;

    /**
     * 登录
     *
     * @param phone    手机号
     * @param password 密码
     * @return 响应结果
     */
    @PostMapping(value = "/account")
    public Result login(String phone, String password, HttpServletRequest request) {

        //判断曾经登录是否还在有效期
        String token_ = request.getHeader("token");
        //判断token是否存在
        if (StringUtils.hasText(token_)) {
            String claim = JwtUtils.getClaim(token_);
            if (StringUtils.hasText(claim) && claim.equals(phone)) {
                //从redis中删除
                String key = "login:token:" + token_;
                redisClient.del(key);
            }
        }
        String clientIP = IpUtils.getClientIP(request);

        //封装用户名和密码
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(phone, password);

        /*
         * 调用认证方法
         * Authentication: 如果成功,封装了用户的全部信息，认证/授权
         */
        try {
            System.out.println(authenticationToken.getPrincipal());
            Authentication authenticate = authenticationManager.authenticate(authenticationToken);
            if (Objects.isNull(authenticate)) {
                return Result.failure("用户名或密码错误");
            }

            //生成token
            String token = JwtUtils.sign(phone, 1000 * 60 * 60 * 24 * 7L);
            //将生成的token保存到redis中
            String key = "login:token:" + token;
            //将用户信息json化
            LoginUserDetails principal = (LoginUserDetails) authenticate.getPrincipal();
            String json = JSONUtil.toJsonStr(principal);
            //保存到redis中
            redisClient.set(key, json, 1000 * 60 * 60 * 24 * 7L);
            String usergent = request.getHeader("User-Agent");

            UserAgent userAgent = UserAgent.parseUserAgentString(usergent);
            Browser browser = userAgent.getBrowser();
            OperatingSystem operatingSystem = userAgent.getOperatingSystem();
            SysAccounts usersVO = principal.getAccounts();
            SysLoginLog adminToken = new SysLoginLog();
            adminToken.setIp(clientIP);

            List<String> perIds = userRoleService.findByPerIds(usersVO.getId());

            String join = String.join(",", perIds);
            adminToken.setPerIds(join);


            List<String> perKeys = userRoleService.findByPerKeys(usersVO.getId());
            String join1 = String.join(",", perKeys);
            adminToken.setPerKeys(join1);

            adminToken.setToken(token);
            adminToken.setBrowser(browser.getName());
            adminToken.setSystemName(operatingSystem.getName());

            adminToken.setVersion(ConstantHeader.getVersion());
            adminToken.setTerminal(String.valueOf(ConstantHeader.getTerminal()));
            //  adminToken.setCreateDate(new Timestamp());
            //    adminToken.set(one.getName());
            //  adminToken.setPort(usersVO);
            adminToken.setUserName(usersVO.getUserName());
            adminToken.setUserId(usersVO.getId());
   /*         adminToken.setDeptId(usersVO.getDeptId());
            adminToken.setOrganId(usersVO.getOrganId());
            adminToken.setOrganType(usersVO.getOrganType());*/


            tokenAdminUtils.getToken(adminToken);
            //将token返回给客户端
            Map<String, Object> map = new HashMap<>();
            map.put("token", token);
            map.put("account", principal.getAccountsVO());
            return Result.ok(map);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.failure("用户名或密码错误");
        }
    }

}
